"""Secret资源Markdown写入器模块"""

from typing import Dict, Any, List
import base64
import json
from src.writers.base import Writer
from src.utils.markdown_builder import MarkdownBuilder

class SecretWriter(Writer):
    """
    Secret资源Markdown写入器
    负责将提取的Secret资源信息写入Markdown文件
    """
    
    def write(self, data: Dict[str, Any], output_path: str) -> None:
        """
        将提取的Secret信息写入Markdown
        
        Args:
            data: 提取的Secret信息
            output_path: 输出文件路径
        """
        if not data or data.get("kind") != "Secret":
            self.logger.warning(f"无效的Secret数据: {data.get('name', '未知')}")
            return
        
        # 创建Markdown构建器
        md = self.create_markdown_builder()
        
        # 收集节标题，用于生成目录
        sections = ["基本信息", "数据内容"]
        
        # 标题
        md.header(f"Secret: {data.get('name', '未知')}", 1)
        
        # 命名空间
        md.bold("命名空间:").text(f" {data.get('namespace', 'default')}").newline(2)
        
        # 目录
        if len(sections) > 2:  # 只有当节较多时才添加目录
            md.toc(sections)
        
        # 基本信息
        self._write_basic_info(md, data)
        
        # 数据内容
        self._write_secret_data(md, data)
        
        # 生成Markdown文件
        self.write_markdown(md, output_path)
    
    def _write_basic_info(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入基本信息
        
        Args:
            md: Markdown构建器
            data: Secret数据
        """
        md.header("基本信息", 2)
        
        # 基本元数据表
        basic_info = {
            "名称": data.get("name", ""),
            "命名空间": data.get("namespace", "default"),
            "创建时间": data.get("creation_timestamp", ""),
            "类型": data.get("type", "Opaque"),
            "数据项数量": len(data.get("data", {})) + len(data.get("string_data", {}))
        }
        
        # Secret类型解释
        secret_type = data.get("type", "Opaque")
        type_description = {
            "Opaque": "通用Secret，任意用户定义的数据",
            "kubernetes.io/service-account-token": "服务账号令牌",
            "kubernetes.io/dockercfg": "~/.dockercfg文件的序列化形式",
            "kubernetes.io/dockerconfigjson": "~/.docker/config.json文件的序列化形式",
            "kubernetes.io/basic-auth": "基本认证凭证",
            "kubernetes.io/ssh-auth": "SSH认证凭证",
            "kubernetes.io/tls": "TLS证书和私钥",
            "bootstrap.kubernetes.io/token": "启动引导令牌数据"
        }
        
        if secret_type in type_description:
            basic_info["类型说明"] = type_description[secret_type]
        
        md.dict_table(basic_info)
        
        # 标签和注解
        if data.get("labels"):
            md.header("标签", 3)
            md.dict_table(data.get("labels", {}))
        
        if data.get("annotations"):
            md.header("注解", 3)
            md.dict_table(data.get("annotations", {}))
    
    def _write_secret_data(self, md: MarkdownBuilder, data: Dict[str, Any]) -> None:
        """
        写入Secret数据内容
        
        Args:
            md: Markdown构建器
            data: Secret数据
        """
        md.header("数据内容", 2)
        
        # 获取加密数据和字符串数据
        secret_data = data.get("data", {})
        string_data = data.get("string_data", {})
        
        # 数据项数信息
        total_items = len(secret_data) + len(string_data)
        md.paragraph(f"共有 **{total_items}** 项数据")
        
        # 处理Secret类型特定的内容
        secret_type = data.get("type", "Opaque")
        
        if secret_type == "kubernetes.io/tls":
            self._write_tls_secret(md, secret_data)
        elif secret_type == "kubernetes.io/dockerconfigjson":
            self._write_docker_config_secret(md, secret_data)
        elif secret_type == "kubernetes.io/service-account-token":
            self._write_service_account_token(md, secret_data)
        elif secret_type == "kubernetes.io/basic-auth":
            self._write_basic_auth_secret(md, secret_data)
        elif secret_type == "kubernetes.io/ssh-auth":
            self._write_ssh_auth_secret(md, secret_data)
        else:
            # 通用Secret数据处理
            self._write_generic_secret_data(md, secret_data, string_data)
    
    def _write_tls_secret(self, md: MarkdownBuilder, secret_data: Dict[str, Any]) -> None:
        """
        写入TLS类型Secret的特定内容
        
        Args:
            md: Markdown构建器
            secret_data: Secret加密数据
        """
        md.header("TLS证书信息", 3)
        
        # TLS Secret通常包含以下键
        tls_keys = ["tls.crt", "tls.key", "ca.crt"]
        
        # 检查是否包含证书和私钥
        has_cert = "tls.crt" in secret_data
        has_key = "tls.key" in secret_data
        has_ca = "ca.crt" in secret_data
        
        with md.list() as lst:
            if has_cert:
                lst.item("包含TLS证书 (tls.crt)")
                # 尝试解析证书以获取更多信息（例如过期日期、主题等）
                try:
                    cert_data = base64.b64decode(secret_data["tls.crt"]).decode("utf-8")
                    # 这里可以添加更多证书解析逻辑
                    cert_lines = cert_data.count("-----BEGIN CERTIFICATE-----")
                    if cert_lines > 0:
                        lst.item(f"证书链包含 {cert_lines} 个证书")
                except:
                    pass
            
            if has_key:
                lst.item("包含私钥 (tls.key)")
            
            if has_ca:
                lst.item("包含CA证书 (ca.crt)")
        
        # 检查是否有其他未识别的TLS相关键
        other_keys = [k for k in secret_data.keys() if k not in tls_keys]
        if other_keys:
            md.paragraph("其他TLS相关数据项:")
            with md.list() as lst:
                for key in other_keys:
                    lst.item(f"`{key}`")
    
    def _write_docker_config_secret(self, md: MarkdownBuilder, secret_data: Dict[str, Any]) -> None:
        """
        写入Docker配置类型Secret的特定内容
        
        Args:
            md: Markdown构建器
            secret_data: Secret加密数据
        """
        md.header("Docker Registry认证信息", 3)
        
        # Docker配置通常存储在.dockerconfigjson键中
        if ".dockerconfigjson" in secret_data:
            try:
                # 解码并解析Docker配置JSON
                docker_config_str = base64.b64decode(secret_data[".dockerconfigjson"]).decode("utf-8")
                docker_config = json.loads(docker_config_str)
                
                # 提取认证服务器信息
                if "auths" in docker_config:
                    auths = docker_config["auths"]
                    
                    md.paragraph("配置了以下Docker Registry认证:")
                    
                    headers = ["Registry地址", "认证类型"]
                    rows = []
                    
                    for registry, auth_data in auths.items():
                        auth_type = "用户名密码" if "auth" in auth_data else "其他"
                        rows.append([registry, auth_type])
                    
                    md.table(headers, rows)
            except Exception as e:
                md.paragraph(f"Docker认证信息解析失败: {str(e)}")
        else:
            md.paragraph("未找到标准的Docker配置(.dockerconfigjson)")
            
            # 检查旧版格式
            if ".dockercfg" in secret_data:
                md.paragraph("包含旧版Docker配置(.dockercfg)")
    
    def _write_service_account_token(self, md: MarkdownBuilder, secret_data: Dict[str, Any]) -> None:
        """
        写入服务账号令牌类型Secret的特定内容
        
        Args:
            md: Markdown构建器
            secret_data: Secret加密数据
        """
        md.header("服务账号令牌信息", 3)
        
        # 服务账号令牌通常包含以下键
        token_keys = ["token", "ca.crt", "namespace"]
        
        with md.list() as lst:
            for key in token_keys:
                if key in secret_data:
                    if key == "token":
                        lst.item("包含服务账号令牌")
                    elif key == "ca.crt":
                        lst.item("包含CA证书")
                    elif key == "namespace":
                        try:
                            ns = base64.b64decode(secret_data[key]).decode("utf-8")
                            lst.item(f"命名空间: {ns}")
                        except:
                            lst.item("包含命名空间信息")
        
        # 检查是否有其他未识别的键
        other_keys = [k for k in secret_data.keys() if k not in token_keys]
        if other_keys:
            md.paragraph("其他服务账号相关数据项:")
            with md.list() as lst:
                for key in other_keys:
                    lst.item(f"`{key}`")
    
    def _write_basic_auth_secret(self, md: MarkdownBuilder, secret_data: Dict[str, Any]) -> None:
        """
        写入基本认证类型Secret的特定内容
        
        Args:
            md: Markdown构建器
            secret_data: Secret加密数据
        """
        md.header("基本认证信息", 3)
        
        # 基本认证通常包含以下键
        has_username = "username" in secret_data
        has_password = "password" in secret_data
        
        with md.list() as lst:
            if has_username:
                try:
                    username = base64.b64decode(secret_data["username"]).decode("utf-8")
                    lst.item(f"用户名: `{username}`")
                except:
                    lst.item("包含用户名")
            
            if has_password:
                lst.item("包含密码 (已隐藏)")
        
        # 检查是否有其他未识别的键
        other_keys = [k for k in secret_data.keys() if k not in ["username", "password"]]
        if other_keys:
            md.paragraph("其他认证相关数据项:")
            with md.list() as lst:
                for key in other_keys:
                    lst.item(f"`{key}`")
    
    def _write_ssh_auth_secret(self, md: MarkdownBuilder, secret_data: Dict[str, Any]) -> None:
        """
        写入SSH认证类型Secret的特定内容
        
        Args:
            md: Markdown构建器
            secret_data: Secret加密数据
        """
        md.header("SSH认证信息", 3)
        
        # SSH认证通常包含ssh-privatekey键
        if "ssh-privatekey" in secret_data:
            md.paragraph("包含SSH私钥")
            
            try:
                # 尝试获取私钥的类型信息
                ssh_key = base64.b64decode(secret_data["ssh-privatekey"]).decode("utf-8")
                if "BEGIN RSA PRIVATE KEY" in ssh_key:
                    md.paragraph("私钥类型: RSA")
                elif "BEGIN DSA PRIVATE KEY" in ssh_key:
                    md.paragraph("私钥类型: DSA")
                elif "BEGIN EC PRIVATE KEY" in ssh_key:
                    md.paragraph("私钥类型: EC")
                elif "BEGIN OPENSSH PRIVATE KEY" in ssh_key:
                    md.paragraph("私钥类型: OpenSSH")
            except:
                pass
        
        # 检查是否有其他未识别的键
        other_keys = [k for k in secret_data.keys() if k != "ssh-privatekey"]
        if other_keys:
            md.paragraph("其他SSH相关数据项:")
            with md.list() as lst:
                for key in other_keys:
                    lst.item(f"`{key}`")
    
    def _write_generic_secret_data(self, md: MarkdownBuilder, secret_data: Dict[str, Any], string_data: Dict[str, Any]) -> None:
        """
        写入通用Secret数据表
        
        Args:
            md: Markdown构建器
            secret_data: Secret加密数据
            string_data: Secret字符串数据
        """
        # 如果没有数据
        if not secret_data and not string_data:
            md.paragraph("无数据内容")
            return
        
        md.header("数据项", 3)
        
        # 创建数据项表
        headers = ["键", "大小", "类型"]
        rows = []
        
        # 处理加密数据
        for key, value in secret_data.items():
            try:
                # Base64解码数据以获取实际大小
                raw_value = base64.b64decode(value)
                size = len(raw_value)
                
                # 尝试确定数据类型
                data_type = self._guess_data_type(key, raw_value)
                
                rows.append([key, f"{size} 字节", data_type])
            except:
                rows.append([key, "无法解码", "未知"])
        
        # 处理字符串数据
        for key, value in string_data.items():
            size = len(value)
            data_type = self._guess_data_type(key, value.encode("utf-8"))
            rows.append([key, f"{size} 字节", f"{data_type} (未加密)"])
        
        md.table(headers, rows)
        
        # 对于关键Secret数据，不展示实际内容，只显示元信息
        md.paragraph("**注意:** 出于安全考虑，Secret的实际内容不在此展示。")
    
    def _guess_data_type(self, key: str, value: bytes) -> str:
        """
        根据键名和值猜测数据类型
        
        Args:
            key: 数据键名
            value: 二进制数据值
            
        Returns:
            数据类型字符串
        """
        # 根据文件扩展名猜测
        extension_map = {
            ".json": "JSON文件",
            ".yaml": "YAML文件",
            ".yml": "YAML文件",
            ".xml": "XML文件",
            ".conf": "配置文件",
            ".properties": "属性文件",
            ".txt": "文本文件",
            ".sh": "Shell脚本",
            ".bat": "批处理脚本",
            ".pem": "PEM证书/密钥",
            ".crt": "证书文件",
            ".key": "密钥文件",
            ".p12": "PKCS#12文件",
            ".jks": "Java密钥库"
        }
        
        # 查找最后一个点后面的内容作为扩展名
        extension = ""
        if "." in key:
            extension = "." + key.split(".")[-1].lower()
            if extension in extension_map:
                return extension_map[extension]
        
        # 根据常见的键名猜测
        key_lower = key.lower()
        if "password" in key_lower or "secret" in key_lower or "token" in key_lower:
            return "密码/令牌"
        elif "key" in key_lower:
            return "密钥"
        elif "cert" in key_lower or "ca" in key_lower:
            return "证书"
        elif "config" in key_lower:
            return "配置文件"
        
        # 尝试判断是否为纯文本
        try:
            value.decode("utf-8")
            return "文本"
        except:
            pass
        
        # 默认未知类型
        return "二进制数据"